/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#pragma once

#include <string>
#include <map>

#include "Commands.h"
#include "shared/geom.h"

/**
 * Console varible struct - holds
 * scriptable variables
 */
struct cvar  {
    float           fvalue;
    std::string     svalue;
    std::string     name;
    MVector3f       vector;
    
    int     flags;
    bool    valid;
    
    cvar():fvalue(0),flags(0),valid(false) {};
    virtual ~cvar(){};
};

// shortcut
typedef std::map< std::string, cvar* > type_CvarList;

/**
====================================
This class stores all console variables

A console variable is used to tweaking and/or storing persistant variables.
One may edit a cvar through the console command 'set [cvar name]'.
====================================
*/
class Kernel;
class Cvars
{
public:
    Cvars(void);
    /** Initialize the cvar system */
    void Init( Kernel* kernel );

    /** Get a cvar float value */
    float GetFloatValue( const std::string &cvar_name );
    /** Get a string value */
    std::string GetStringValue( const std::string &cvar_name );
    /** Get a vector */
    MVector3f   GetVectorValue( const std::string &cvar_name );

    /** Create a cvar */
	void RegisterCvar( const std::string &name, const std::string &sval, float v1=0, float v2=0, float v3=0, bool b=false, int Flags=0 );
    /** Remove a cvar */
	void RemoveCvar( const std::string &cvar_name );

    /** Set a cvar value */
	bool SetCvarValue( const std::string &name, float val );
    bool SetCvarValue( const std::string &name, const std::string &value);
    bool SetCvarValue( const std::string &name, const MVector3f &v );

    /** Retrieve the cvar list */
    const type_CvarList& GetCvars() { return cvarList; };
    /** Test to see if the given name is a valid cvar */
    bool IsValid(const std::string &name);

private:
    /** Retreive a Cvar */
    cvar* GetCvar( const std::string &cvarName );
    type_CvarList   cvarList; // hashmap of cvars
    //EntDict         m_cvarList;
    /**
    =====================
    List available cvars
    =====================
    */
    class List_f : public ICommand
    {
    public:
        List_f() : m_cvars(NULL) {};
        void Exec(std::string &s);
        /** Set the cvar system */
        void Set( Cvars* c ) { m_cvars = c; };
        virtual ~List_f() {};
    private:
        Cvars*  m_cvars;
    };
    friend List_f;
    List_f      m_listCmd;
public:
    virtual ~Cvars(void);
};


/**
==========================================
Console variable flags
==========================================
*/
enum {
// Saveable cvar setting
    CVAR_SAVE=       1,
// Do not allow changes 
    CVAR_PROTECT=    2,
// Server Access only
    CVAR_SERVER=     4,
// Bindable 
    CVAR_BIND=       8
};


